package com.ruoyi.common.websocket;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

@Component
@ServerEndpoint("/arcus/vue/monitor/websocket/{userId}")
public class VueWebSocket implements IWebSocket{
    private static final Logger log = LoggerFactory.getLogger(VueWebSocket.class);

    private String userId;
    private Session session;


    private void closeSession(String userId) throws IOException{
        VueWebSocket vueWebSocket = (VueWebSocket) IWebSocket.vueSocket.get(userId);
        vueWebSocket.session.close();
    }

    private void printSessionInfo(){
        log.info("A new vue socket connect, details is: ");
        log.info("  -- session id is: " + session.getId());
        log.info("  -- protocol version is: " + session.getProtocolVersion());
        log.info("  -- request uri is: " + session.getRequestURI().toString());
        log.info("  -- userId is: " + userId);
        log.info("  -- online user number is: " + IWebSocket.vueSocket.size());

    }

    @OnOpen
    @Override
    public void connect(Session session, @PathParam(value = "userId") String uuid) {
        this.userId = uuid;
        this.session = session;

        // TODO
        //     uni-app页面跳转的时候生成多session
        //     关闭旧的session后，又由于uni-app只维护一个websocket
        //     导致前台websocket直接close然后重连
        //     由于uni.closeSocket失效所以这里只会触发重连会话删除
        //     所幸this.ws.close()有效，前台结束socket后
        //     后台删除session对象，重新链接的时候又保持一个能正常运行
        if(IWebSocket.vueSocket.containsKey(userId)){
            log.info("A vue socket re-connect, try delete session before");
            try {
                this.closeSession(userId);
            }catch (Exception e){
                e.printStackTrace();
            }
            IWebSocket.vueSocket.put(userId, this);
            log.info("User " + userId + " now re-connect success");
        }else{
            IWebSocket.vueSocket.put(userId, this);
        }

        this.printSessionInfo();
    }

    @OnClose
    @Override
    public void disConnect() {
        IWebSocket.vueSocket.remove(this.userId);
        log.warn("A user has dis-connect");
        log.warn(" -- user id is: " + this.userId);
        log.warn(" -- now connect user number is: " + IWebSocket.vueSocket.size());
    }

    @Override
    public void push(String msg) {
        try {
            this.session.getBasicRemote().sendText(msg);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void push(String uuid, String msg) {

    }

    @OnMessage
    @Override
    public void msgArriveDefault(String msg) {
        log.info("arrive msg： " + msg);
        this.push("I have received this msg: " + msg);
    }

    @OnError
    @Override
    public void msgSendError(Session session, Throwable error) {
        log.error("错误");
    }
}

